/* $RCSFile: ADNCRMTraceListener.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/ADNCRM.Core/Configuration/ADNCRMTraceListener.cs $
 * $log$
 * Revision 6 2010/08/06 19:56:27  christian.surieux
 *   Added Log to All cs files
 */

using System;
using System.Diagnostics;
using System.Configuration;
using System.Web;
using System.IO;
using System.Globalization;

using AddonNice.Configuration;
using AddonNice.Settings;

namespace AddonNice.Diagnostics
{
	/// <summary>
	/// Summary description for ADNCRMTraceListener.
	/// </summary>
	public class ADNCRMTraceListener : TextWriterTraceListener
	{
		static string StartDate	=	string.Empty;

        DateTime	Date		        =	DateTime.UtcNow;
        string      lastHeader          =   string.Empty;
        bool        packHeaders         =   true;
        bool        verbose             =   true;
        bool        identInfo           =   true;

		/// <summary>
		/// Default Ctor
		/// </summary>
        public ADNCRMTraceListener(string File,string name) : base(File,name)
		{
		}

        /// <summary>
        /// If packHeader mode is set try to avoid rewritting last header
        /// If verbose mode is not set, doesn't write the header
        /// </summary>
		public ADNCRMTraceListener(string File,string name, bool packHdr,bool verB,bool ident) : base(File,name)
		{
            packHeaders         =   packHdr;
            verbose             =   verB;
            identInfo           =   ident;
		}

		public bool ChangeStorage()
		{
			bool ret					= false;
			lock(Trace.Listeners )
			{
				ret						=	InitSorage(packHeaders,verbose,identInfo);
				Trace.Listeners.Remove(this);
				Close();
			}
			return ret;
		}

		public static bool InitSorage(bool packHdr,bool verB,bool ident)
		{
			string	TraceFile			=	string.Empty;
			bool ret					=	false;
			try
			{
				string	ListenerPrefix	=	Config.TraceListener;
				string	sPath			=	Config.AlternateLogLocation;
				StartDate				=	DateTime.UtcNow.ToString("yy-MM-dd");
                int idx                 =   0;
                
				string wTraceFile		=	string.Format("{0}{1}-{2}{3:D3}.log",sPath,ListenerPrefix,StartDate,idx);
                TraceFile               =   System.IO.Path.GetFullPath(wTraceFile);
                bool exist              =   false;
                while ( System.IO.File.Exists(TraceFile) && idx < 1000)
                {
                    idx++;
                    exist               =   true;
				    wTraceFile		    =	string.Format("{0}{1}-{2}{3:D3}.log",new object[]{sPath,ListenerPrefix,StartDate,idx});
                    TraceFile           =   System.IO.Path.GetFullPath(wTraceFile);
                }
                TraceListener Twl		=	Trace.Listeners[ListenerPrefix];
                if ( Twl == null )
                {
                    Twl					=	new ADNCRMTraceListener(TraceFile,ListenerPrefix,packHdr,verB,ident);
				    Trace.Listeners.Add(Twl);
                }
				Twl.WriteLine(string.Format("{0}Starting Trace at : {1:u}, pack headers: {2}, mode verbose: {3}, mode ident: {4}, exist file: {5}.",
                    new object[]{Environment.NewLine,DateTime.UtcNow,packHdr,verB,ident, exist}));
				ret						=	true;
			}
			catch(Exception ex)
			{
				if ( GlobalTraceSwitch.Sw.TraceError )
                    Trace.WriteLine( string.Format(CultureInfo.InvariantCulture,"Error Installing the Trace File : {0} ex : {1}",TraceFile,ex),GlobalTraceSwitch.Sw.Info);
			}
			return ret;
		}

        protected void WriteHeader()
        {
            WriteHeader(string.Empty);
        }
		
        /// <summary>
        /// Write a header before each trace info: Date-Time + if the portalSetting info is found in session PortalID,PortalAlias
        /// If packHeader mode is set try to avoid rewritting last header
        /// If verbose mode is not set, doesn't write the header
        /// </summary>
        protected void WriteHeader(string cat)
		{
            if ( !verbose )
                return;
		    
            PortalSettings portalSettings   =   null;

			if ( HttpContext.Current != null )
			{
				object ob	                =   HttpContext.Current.Items[StStr.strPortalSettings];
				if ( ob != null )
				    portalSettings          =   (PortalSettings) ob;
			}
            string strHdr                   =   string.Empty;
			if ( portalSettings != null )
				    strHdr                  =   string.Format("{0} : Portal : {1}-{2} : {3}",
                        new object[]{DateTime.UtcNow.ToLongTimeString(),portalSettings.PortalID,portalSettings.PortalAlias,cat});
			else    strHdr                  =   string.Format("{0} : Portal :   -     : {1}",DateTime.UtcNow.ToLongTimeString(),cat);
            if ( packHeaders && strHdr.Equals(lastHeader) )
                return;
            lastHeader                      =   strHdr;
            base.WriteLine(lastHeader);
			// we ident next line
            if (!packHeaders && identInfo )
            {
                NeedIndent                  =   true;
                base.WriteIndent();
            }
		}

		public override void WriteLine(string str)
		{
			WriteHeader();
			base.WriteLine(str);
		}
		public override void WriteLine(object o,string cat)
		{
			WriteHeader(cat);
			base.WriteLine(o);
		}
		public override void WriteLine(string message,string cat)
		{
			WriteHeader(cat);
			base.WriteLine(message);
		}
		public override void WriteLine(object o)
		{
			WriteHeader();
			base.WriteLine(o);
		}

		public override void Write(string str)
		{
			WriteHeader();
			base.Write(str);
		}
		public override void Write(object o,string cat)
		{
			WriteHeader(cat);
			base.Write(o);
		}
		public override void Write(string message,string cat)
		{
			WriteHeader(cat);
			base.Write(message);
		}
		public override void Write(object o)
		{
			WriteHeader();
			base.Write(o);
		}

		public override void Fail(string o)
		{
			base.Fail(o);
		}

		public override void Fail(string o,string s)
		{
			base.Fail(o,s);
		}

		public override void Flush()
		{
			base.Flush();
			string wDate				=	DateTime.UtcNow.ToString("yy-MM-dd");
			if ( wDate != StartDate )
				ChangeStorage();
			}
		
		public override void Close()
		{
			WriteHeader();
			base.Write("Closing Trace");
			base.Close();
		}
	}
}
